home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Internet / WWW / swish.11 / src / string.c < prev    next >
C/C++ Source or Header  |  1995-03-11  |  12KB  |  502 lines

  1. /*
  2. ** Copyright (C) 1995, Enterprise Integration Technologies Corp.        
  3. ** All Rights Reserved.
  4. ** Kevin Hughes, kevinh@eit.com 
  5. ** 3/11/94
  6. */
  7.  
  8. #include "swish.h"
  9. #include "string.h"
  10.  
  11. /* My own case-insensitive strstr().
  12. */
  13.  
  14. char *lstrstr(s, t)
  15.      char *s;
  16.      char *t;
  17. {
  18.  
  19.     int i, j, k, l;
  20.  
  21.     for (i = 0; s[i]; i++) {
  22.         for (j = 0, l = k = i; s[k] && t[j] &&
  23.         tolower(s[k]) == tolower(t[j]); j++, k++)
  24.             ;
  25.         if (t[j] == '\0')
  26.             return s + l;
  27.     }
  28.     return NULL;
  29. }
  30.  
  31. /* Gets the next word in a line. If the word's in quotes,
  32. ** include blank spaces in the word or phrase.
  33. */
  34.  
  35. char *getword(line, skiplen)
  36.      char *line;
  37.      int *skiplen;
  38. {
  39.         int i, inquotes;
  40.         char *start;
  41.         static char word[MAXSTRLEN];
  42.  
  43.         start = line;
  44.         if (!(*line))
  45.                 return "\0";
  46.         while (isspace(*line))
  47.                 line++;
  48.         if (!(*line))
  49.                 return "\0";
  50.         if (*line == '\"') {
  51.                 inquotes = 1;
  52.                 line++;
  53.         }
  54.         else
  55.                 inquotes = 0;
  56.         for (i = 0; *line && i < MAXSTRLEN &&
  57.         ((inquotes) ? (*line != '\"') : (!isspace(*line))); line++)
  58.                 word[i++] = *line;
  59.         word[i] = '\0';
  60.         if (!(*line))
  61.                 return "\0";
  62.         if (*line == '\"')
  63.                 line++;
  64.  
  65.         *skiplen = line - start;
  66.  
  67.         return word;
  68. }
  69.  
  70. /* Gets the value of a variable in a line of the configuration file.
  71. ** Basically, anything in quotes or an argument to a variable.
  72. */
  73.  
  74. char *getconfvalue(line, var, value)
  75.      char *line;
  76.      char *var;
  77.      char *value;
  78. {
  79.         int i;
  80.         char *c;
  81.         static char tmpvalue[MAXSTRLEN];
  82.  
  83.         if ((c = (char *) lstrstr(line, var)) != NULL) {
  84.                 if (c != line)
  85.                         return NULL;
  86.                 c += strlen(var);
  87.                 while (isspace(*c) || *c == '\"')
  88.                         c++;
  89.                 if (*c == '\0')
  90.                         return NULL;
  91.                 for (i = 0; *c != '\0' && *c != '\"' && *c != '\n' &&
  92.                 i < MAXSTRLEN; c++)
  93.                         tmpvalue[i++] = *c;
  94.                 tmpvalue[i] = '\0';
  95.                 strcpy(value, tmpvalue);
  96.                 return tmpvalue;
  97.         }
  98.         else
  99.                 return NULL;
  100. }
  101.  
  102. /* Extracts anything in <title> tags from an HTML file and returns it.
  103. ** Otherwise, only the file name without its path is returned.
  104. */
  105.  
  106. char *parsetitle(filename)
  107.      char *filename;
  108. {
  109.         register int c, d;
  110.     register char *p;
  111.     char *tag;
  112.         static char title[MAXTITLELEN], shorttitle[MAXTITLELEN];
  113.         int i, j, lines, status, tagbuflen, totaltaglen;
  114.         FILE *fp;
  115.  
  116.     tag = (char *) emalloc(1);
  117.     tag[0] = '\0';
  118.         lines = status = 0;
  119.         p = title;
  120.         *p = '\0';
  121.  
  122.         if (strrchr(filename, '/'))
  123.                 strcpy(shorttitle, strrchr(filename, '/') + 1);
  124.     else
  125.                 strcpy(shorttitle, filename);
  126.  
  127.         fp = fopen(filename, "r");
  128.         if (fp == NULL) {
  129.         free(tag);
  130.                 return shorttitle;
  131.     }
  132.         for (; lines < TITLETOPLINES ; ) {
  133.                 c = getc(fp);
  134.                 if (c == '\n')
  135.                         lines++;
  136.                 if (feof(fp)) {
  137.                         fclose(fp);
  138.             free(tag);
  139.                         return shorttitle;
  140.                 }
  141.                 switch(c) {
  142.                 case '<':
  143.  
  144.             free(tag);
  145.             tag = (char *) emalloc(MAXSTRLEN);
  146.             tag[0] = '\0';
  147.             tagbuflen = totaltaglen = 0;
  148.  
  149.             tag[totaltaglen++] = '<';
  150.             tagbuflen++;
  151.                         status = TI_OPEN;
  152.  
  153.             while (1) {
  154.                                 d = getc(fp);
  155.                                 if (d == EOF) {
  156.                     fclose(fp);
  157.                     free(tag);
  158.                     return shorttitle;
  159.                 }
  160.                 else if (d == '>') {
  161.                     tag[totaltaglen] = '\0';
  162.                     tag = (char *) erealloc(tag,
  163.                     totaltaglen + MAXSTRLEN);
  164.                     sprintf(tag, "%s%c", tag, '>');
  165.                     break;
  166.                 }
  167.  
  168.                 tag[totaltaglen++] = d;
  169.                 tagbuflen++;
  170.                 if (tagbuflen >= MAXSTRLEN) {
  171.                     tag = (char *) erealloc(tag,
  172.                     totaltaglen + MAXSTRLEN);
  173.                     tagbuflen = 0;
  174.                 }
  175.             }
  176.  
  177.                         if (lstrstr(tag, "</title>")) {
  178.                                 status = TI_CLOSE;
  179.                                 *p = '\0';
  180.                                 fclose(fp);
  181.                                 for (i = 0; title[i]; i++)
  182.                                         if (title[i] == '\n')
  183.                                                 title[i] = ' ';
  184.                 for (i = 0; isspace(title[i]) ||
  185.                 title[i] == '\"'; i++)
  186.                     ;
  187.                 for (j = 0; title[i]; j++)
  188.                     title[j] = title[i++];
  189.                 for (j = strlen(title) - 1;
  190.                 (j && isspace(title[j]))
  191.                 || title[j] == '\0' || title[j] == '\"'; j--)
  192.                     title[j] = '\0';
  193.                 for (j = 0; title[j]; j++)
  194.                     if (title[j] == '\"')
  195.                         title[j] = '\'';
  196.                 free(tag);
  197.                                 return title;
  198.                         }
  199.                         else {
  200.                                 if (lstrstr(tag, "<title>"))
  201.                                         status = TI_FOUND;
  202.                         }
  203.                         break;
  204.                 default:
  205.                         if (status == TI_FOUND) {
  206.                                 *p = c;
  207.                                 p++;
  208.                         }
  209.                         else {
  210.                                 if (status == TI_CLOSE) {
  211.                                         fclose(fp);
  212.                     free(tag);
  213.                                         return shorttitle;
  214.                                 }
  215.                         }
  216.                 }
  217.         }
  218.         fclose(fp);
  219.     free(tag);
  220.         return shorttitle;
  221. }
  222.  
  223. /* Malloc()'s a string, returns it.
  224. */
  225.  
  226. char *mystrdup(s)
  227.      char *s;
  228. {
  229.         char *p;
  230.  
  231.         p = (char *) emalloc(strlen(s) + 1);
  232.         strcpy(p, s);
  233.         return p;
  234. }
  235.  
  236. /* Is a character a valid word character?
  237. */
  238.  
  239. int iswordchar(c)
  240.      char c;
  241. {
  242.     int d, i;
  243.  
  244.     d = tolower(c);
  245.     for (i = 0; WORDCHARS[i] != '\0'; i++)
  246.         if (d == WORDCHARS[i])
  247.             return 1;
  248.         return 0;
  249. }
  250.  
  251. /* In a string, replaces all occurrences of "oldpiece" with "newpiece".
  252. ** This is not really bulletproof yet.
  253. */
  254.  
  255. char *replace(string, oldpiece, newpiece)
  256.      char *string;
  257.      char *oldpiece;
  258.      char *newpiece;
  259. {
  260.         int i, j, limit;
  261.         char *c;
  262.         char beforestring[MAXSTRLEN], afterstring[MAXSTRLEN];
  263.         static char newstring[MAXSTRLEN];
  264.  
  265.         if ((c = (char *) strstr(string, oldpiece)) == NULL)
  266.                 return string;
  267.         limit = c - string;
  268.  
  269.         for (i = 0; i < limit; i++)
  270.                 beforestring[i] = string[i];
  271.         beforestring[i] = '\0';
  272.  
  273.         i += strlen(oldpiece);
  274.  
  275.         for (j = 0; string[i] != '\0'; i++)
  276.                 afterstring[j++] = string[i];
  277.         afterstring[j] = '\0';
  278.  
  279.         sprintf(newstring, "%s%s%s", beforestring, newpiece, afterstring);
  280.  
  281.         while (strstr(newstring, oldpiece))
  282.                 strcpy(newstring, replace(newstring, oldpiece, newpiece));
  283.  
  284.         return newstring;
  285. }
  286.  
  287. /* Like strcmp(), but the order of sorting the first char is
  288. ** determined by the order of the characters in the wordchars array.
  289. */
  290.  
  291. int wordcompare(s1, s2)
  292.      char *s1;
  293.      char *s2;
  294. {
  295.     register int i, j;
  296.  
  297.     if (s1[0] != s2[0]) {
  298.         for (i = 0; WORDCHARS[i] != '\0'; i++)
  299.             if (s1[0] == WORDCHARS[i])
  300.                 break;
  301.         for (j = 0; WORDCHARS[j] != '\0'; j++)
  302.             if (s2[0] == WORDCHARS[j])
  303.                 break;
  304.         if (i < j)
  305.             return -1;
  306.         else
  307.             return 1;
  308.     }
  309.     else
  310.         return strcmp(s1, s2);
  311. }
  312.  
  313. /* This converts HTML numbered entities (such as ©)
  314. ** to strings (like ©). Much is this function is
  315. ** simply adding semicolons in the right places.
  316. ** This and the functions it calls are not very fast
  317. ** and could be made faster.
  318. */
  319.  
  320. char *convertentities(s)
  321.      char *s;
  322. {
  323.     int i, skip;
  324.     char ent[MAXENTLEN];
  325.     static char newword[MAXWORDLEN];
  326.  
  327.     if ((char *) strchr(s, '&') == NULL)
  328.         return s;
  329.     if (strlen(s) > MAXWORDLIMIT)
  330.         return s;
  331.  
  332.     for (i = 0; i < MAXWORDLEN; i++)
  333.         newword[i] = '\0';
  334.     for (; *s != '\0'; s++) {
  335.         if (*s == '&') {
  336.             strcpy(ent, getent(s, &skip));
  337.             if (ent[0] == '\0') {
  338.                 sprintf(newword, "%s&", newword);
  339.                 continue;
  340.             }
  341.             s += skip;
  342.             if (*s == ';')
  343.                 s++;
  344.             sprintf(newword, "%s%s;", newword, ent);
  345.             s--;
  346.         }
  347.         else
  348.             sprintf(newword, "%s%c", newword, *s);
  349.     }
  350.  
  351.     strcpy(newword, (char *) converttonamed(newword));
  352.     if (ASCIIENTITIES)
  353.         strcpy(newword, (char *) converttoascii(newword));
  354.  
  355.     return newword;
  356. }
  357.  
  358. /* Returns a matching entity that matches the beginning of a string, if any.
  359. */
  360.  
  361. char *getent(s, skip)
  362.      char *s;
  363.      int *skip;
  364. {
  365.     int i;
  366.     static char ent[MAXENTLEN], testent[MAXENTLEN];
  367.  
  368.     *skip = 0;
  369.     strncpy(ent, s, MAXENTLEN);
  370.     if (ent[1] == '#') {
  371.         if (isdigit(ent[5]))
  372.             return "\0";
  373.         for (i = 2; ent[i] != '\0' && isdigit(ent[i]); i++)
  374.             ;
  375.         while (ent[i] != '\0' && !isdigit(ent[i]))
  376.             ent[i++] = '\0';
  377.         *skip = strlen(ent);
  378.         return ent;
  379.     }
  380.     else {
  381.         for (i = 0; entities[i] != NULL; i += 3) {
  382.             strcpy(testent, entities[i]);
  383.             if (testent[0] != '\0') {
  384.                 if (!strncmp(testent, ent, strlen(testent))) {
  385.                     strcpy(ent, testent);
  386.                     *skip = strlen(ent);
  387.                     return ent;
  388.                 }
  389.             }
  390.         }
  391.     }
  392.  
  393.     return "\0";
  394. }
  395.  
  396. /* This is the real function called by convertentities() that
  397. ** changes numbered to named entities.
  398. */
  399.  
  400. char *converttonamed(s)
  401.      char *s;
  402. {
  403.     int i;
  404.     char testent[MAXENTLEN], newent[MAXENTLEN];
  405.     static char newword[MAXWORDLEN];
  406.  
  407.     strcpy(newword, s);
  408.     for (i = 0; entities[i] != NULL; i += 3) {
  409.         sprintf(testent, "%s;", entities[i + 1]);
  410.         if (strstr(newword, testent) != NULL &&
  411.         (entities[i])[0] != '\0') {
  412.             sprintf(newent, "%s;", entities[i]);
  413.             strcpy(newword, (char *) replace(newword,
  414.             testent, newent));
  415.         }
  416.     }
  417.  
  418.     while (hasnumbered(newword))
  419.         strcpy(newword, (char *) converttonamed(newword));
  420.  
  421.     return newword;
  422. }
  423.  
  424. /* Does a string still contain numbered entities that can be converted?
  425. */
  426.  
  427. int hasnumbered(s)
  428.      char *s;
  429. {
  430.     int i;
  431.     char testent[MAXENTLEN];
  432.  
  433.     for (i = 0; entities[i] != NULL; i += 3) {
  434.         sprintf(testent, "%s;", entities[i + 1]);
  435.         if (strstr(s, testent) != NULL && (entities[i])[0] != '\0')
  436.             return 1;
  437.     }
  438.     return 0;
  439. }
  440.  
  441. /* This function converts all convertable named and numbered
  442. ** entities to their ASCII equivalents, if they exist.
  443. */
  444.  
  445. char *converttoascii(s)
  446.      char *s;
  447. {
  448.     int i;
  449.     char *c, *d, wrdent[MAXENTLEN], nument[MAXENTLEN];
  450.     static char newword[MAXWORDLEN];
  451.  
  452.     strcpy(newword, s);
  453.     for (i = 0; entities[i] != NULL; i += 3) {
  454.  
  455.         sprintf(wrdent, "%s;", entities[i]);
  456.         sprintf(nument, "%s;", entities[i + 1]);
  457.  
  458.         c = d = NULL;
  459.         if ((entities[i])[0] != '\0')
  460.             c = (char *) strstr(newword, wrdent);
  461.         if ((entities[i + 1])[0] != '\0')
  462.             d = (char *) strstr(newword, nument);
  463.         if ((entities[i + 2])[0] != '\0') {
  464.             if (c != NULL)
  465.                 strcpy(newword, (char *) replace(newword,
  466.                 wrdent, entities[i + 2]));
  467.             if (d != NULL)
  468.                 strcpy(newword, (char *) replace(newword,
  469.                 nument, entities[i + 2]));
  470.         }
  471.     }
  472.  
  473.     while (hasnonascii(newword))
  474.         strcpy(newword, (char *) converttoascii(newword));
  475.  
  476.     return newword;
  477. }
  478.  
  479. /* Does a string still contain numbered or named entities that can
  480. ** be converted to ascii equivalents?
  481. */
  482.  
  483. int hasnonascii(s)
  484.      char *s;
  485. {
  486.     int i;
  487.     char *c, *d;
  488.  
  489.     for (i = 0; entities[i] != NULL; i += 3) {
  490.         c = d = NULL;
  491.         if ((entities[i])[0] != '\0')
  492.             c = (char *) strstr(s, entities[i]);
  493.         if ((entities[i + 1])[0] != '\0')
  494.             d = (char *) strstr(s, entities[i + 1]);
  495.         if ((entities[i + 2])[0] != '\0')
  496.             if (c != NULL || d != NULL)
  497.                 return 1;
  498.     }
  499.  
  500.     return 0;
  501. }
  502.